package cn.kk.fluidcells.cells.keyboard.internal;
import cn.kk.fluidcells.api.InputEvent;
import cn.kk.fluidcells.cells.keyboard.KeyCode;
import cn.kk.fluidcells.cells.keyboard.KeyLocation;

public final class KeyboardHelper implements MediaCodeSupport {

    public static KeyCode getKeyCode(final int rawCode) {
        KeyCode keyCode;
        switch (rawCode) {
            case VK_FN:
                keyCode = KeyCode.VK_FN;
                break;
            case VK_RETURN:
                keyCode = KeyCode.VK_ENTER;
                break;
            case VK_BACK:
                keyCode = KeyCode.VK_BACK_SPACE;
                break;
            case VK_TAB:
                keyCode = KeyCode.VK_TAB;
                break;
            case VK_CANCEL:
                keyCode = KeyCode.VK_CANCEL;
                break;
            case VK_LSHIFT:
                keyCode = KeyCode.VK_SHIFT;
                break;
            case VK_LCONTROL:
                keyCode = KeyCode.VK_CONTROL;
                break;
            case VK_LMENU:
                keyCode = KeyCode.VK_ALT;
                break;
            case VK_LWIN:
                keyCode = KeyCode.VK_WINDOWS;
                break;
            case VK_RSHIFT:
                keyCode = KeyCode.VK_SHIFT;
                break;
            case VK_RCONTROL:
                keyCode = KeyCode.VK_CONTROL;
                break;
            case VK_RMENU:
                keyCode = KeyCode.VK_ALT;
                break;
            case VK_RWIN:
                keyCode = KeyCode.VK_WINDOWS;
                break;
            case VK_APPS:
                keyCode = KeyCode.VK_CONTEXT_MENU;
                break;
            case VK_PAUSE:
                keyCode = KeyCode.VK_PAUSE;
                break;
            case VK_CAPITAL:
                keyCode = KeyCode.VK_CAPS_LOCK;
                break;
            case VK_ESCAPE:
                keyCode = KeyCode.VK_ESCAPE;
                break;
            case VK_SPACE:
                keyCode = KeyCode.VK_SPACE;
                break;
            case VK_UP:
                keyCode = KeyCode.VK_UP;
                break;
            case VK_DOWN:
                keyCode = KeyCode.VK_DOWN;
                break;
            case VK_LEFT:
                keyCode = KeyCode.VK_LEFT;
                break;
            case VK_RIGHT:
                keyCode = KeyCode.VK_RIGHT;
                break;
            case VK_OEM_COMMA:
                keyCode = KeyCode.VK_COMMA;
                break;
            case VK_OEM_MINUS:
                keyCode = KeyCode.VK_MINUS;
                break;
            case VK_OEM_PERIOD:
                keyCode = KeyCode.VK_PERIOD;
                break;
            case 0x30:
                keyCode = KeyCode.VK_0;
                break;
            case 0x31:
                keyCode = KeyCode.VK_1;
                break;
            case 0x32:
                keyCode = KeyCode.VK_2;
                break;
            case 0x33:
                keyCode = KeyCode.VK_3;
                break;
            case 0x34:
                keyCode = KeyCode.VK_4;
                break;
            case 0x35:
                keyCode = KeyCode.VK_5;
                break;
            case 0x36:
                keyCode = KeyCode.VK_6;
                break;
            case 0x37:
                keyCode = KeyCode.VK_7;
                break;
            case 0x38:
                keyCode = KeyCode.VK_8;
                break;
            case 0x39:
                keyCode = KeyCode.VK_9;
                break;

            case VK_OEM_1:
                keyCode = KeyCode.VK_SEMICOLON;
                break;
            case VK_OEM_PLUS:
                keyCode = KeyCode.VK_EQUALS;
                break;

            case 0x41:
                keyCode = KeyCode.VK_A;
                break;
            case 0x42:
                keyCode = KeyCode.VK_B;
                break;
            case 0x43:
                keyCode = KeyCode.VK_C;
                break;
            case 0x44:
                keyCode = KeyCode.VK_D;
                break;
            case 0x45:
                keyCode = KeyCode.VK_E;
                break;
            case 0x46:
                keyCode = KeyCode.VK_F;
                break;
            case 0x47:
                keyCode = KeyCode.VK_G;
                break;
            case 0x48:
                keyCode = KeyCode.VK_H;
                break;
            case 0x49:
                keyCode = KeyCode.VK_I;
                break;
            case 0x4A:
                keyCode = KeyCode.VK_J;
                break;
            case 0x4B:
                keyCode = KeyCode.VK_K;
                break;
            case 0x4C:
                keyCode = KeyCode.VK_L;
                break;
            case 0x4D:
                keyCode = KeyCode.VK_M;
                break;
            case 0x4E:
                keyCode = KeyCode.VK_N;
                break;
            case 0x4F:
                keyCode = KeyCode.VK_O;
                break;
            case 0x50:
                keyCode = KeyCode.VK_P;
                break;
            case 0x51:
                keyCode = KeyCode.VK_Q;
                break;
            case 0x52:
                keyCode = KeyCode.VK_R;
                break;
            case 0x53:
                keyCode = KeyCode.VK_S;
                break;
            case 0x54:
                keyCode = KeyCode.VK_T;
                break;
            case 0x55:
                keyCode = KeyCode.VK_U;
                break;
            case 0x56:
                keyCode = KeyCode.VK_V;
                break;
            case 0x57:
                keyCode = KeyCode.VK_W;
                break;
            case 0x58:
                keyCode = KeyCode.VK_X;
                break;
            case 0x59:
                keyCode = KeyCode.VK_Y;
                break;
            case 0x5A:
                keyCode = KeyCode.VK_Z;
                break;

            case VK_OEM_4:
                keyCode = KeyCode.VK_OPEN_BRACKET;
                break;
            case VK_OEM_5:
                keyCode = KeyCode.VK_BACK_SLASH;
                break;
            case VK_OEM_6:
                keyCode = KeyCode.VK_CLOSE_BRACKET;
                break;

            case VK_NUMPAD0:
                keyCode = KeyCode.VK_NUMPAD0;
                break;
            case VK_NUMPAD1:
                keyCode = KeyCode.VK_NUMPAD1;
                break;
            case VK_NUMPAD2:
                keyCode = KeyCode.VK_NUMPAD2;
                break;
            case VK_NUMPAD3:
                keyCode = KeyCode.VK_NUMPAD3;
                break;
            case VK_NUMPAD4:
                keyCode = KeyCode.VK_NUMPAD4;
                break;
            case VK_NUMPAD5:
                keyCode = KeyCode.VK_NUMPAD5;
                break;
            case VK_NUMPAD6:
                keyCode = KeyCode.VK_NUMPAD6;
                break;
            case VK_NUMPAD7:
                keyCode = KeyCode.VK_NUMPAD7;
                break;
            case VK_NUMPAD8:
                keyCode = KeyCode.VK_NUMPAD8;
                break;
            case VK_NUMPAD9:
                keyCode = KeyCode.VK_NUMPAD9;
                break;
            case VK_MULTIPLY:
                keyCode = KeyCode.VK_MULTIPLY;
                break;
            case VK_ADD:
                keyCode = KeyCode.VK_ADD;
                break;
            case VK_SUBTRACT:
                keyCode = KeyCode.VK_SUBTRACT;
                break;
            case VK_DECIMAL:
                keyCode = KeyCode.VK_DECIMAL;
                break;
            case VK_DIVIDE:
                keyCode = KeyCode.VK_DIVIDE;
                break;
            case VK_NUMLOCK:
                keyCode = KeyCode.VK_NUM_LOCK;
                break;
            case VK_SCROLL:
                keyCode = KeyCode.VK_SCROLL_LOCK;
                break;
            case VK_F1:
                keyCode = KeyCode.VK_F1;
                break;
            case VK_F2:
                keyCode = KeyCode.VK_F2;
                break;
            case VK_F3:
                keyCode = KeyCode.VK_F3;
                break;
            case VK_F4:
                keyCode = KeyCode.VK_F4;
                break;
            case VK_F5:
                keyCode = KeyCode.VK_F5;
                break;
            case VK_F6:
                keyCode = KeyCode.VK_F6;
                break;
            case VK_F7:
                keyCode = KeyCode.VK_F7;
                break;
            case VK_F8:
                keyCode = KeyCode.VK_F8;
                break;
            case VK_F9:
                keyCode = KeyCode.VK_F9;
                break;
            case VK_F10:
                keyCode = KeyCode.VK_F10;
                break;
            case VK_F11:
                keyCode = KeyCode.VK_F11;
                break;
            case VK_F12:
                keyCode = KeyCode.VK_F12;
                break;

            case VK_F13:
                keyCode = KeyCode.VK_F13;
                break;
            case VK_F14:
                keyCode = KeyCode.VK_F14;
                break;
            case VK_F15:
                keyCode = KeyCode.VK_F15;
                break;
            case VK_F16:
                keyCode = KeyCode.VK_F16;
                break;
            case VK_F17:
                keyCode = KeyCode.VK_F17;
                break;
            case VK_F18:
                keyCode = KeyCode.VK_F18;
                break;
            case VK_F19:
                keyCode = KeyCode.VK_F19;
                break;
            case VK_F20:
                keyCode = KeyCode.VK_F20;
                break;
            case VK_F21:
                keyCode = KeyCode.VK_F21;
                break;
            case VK_F22:
                keyCode = KeyCode.VK_F22;
                break;
            case VK_F23:
                keyCode = KeyCode.VK_F23;
                break;
            case VK_F24:
                keyCode = KeyCode.VK_F24;
                break;

            case VK_SNAPSHOT:
                keyCode = KeyCode.VK_PRINTSCREEN;
                break;
            case VK_INSERT:
                keyCode = KeyCode.VK_INSERT;
                break;
            case VK_HELP:
                keyCode = KeyCode.VK_HELP;
                break;

            case VK_DELETE:
                keyCode = KeyCode.VK_DELETE;
                break;

            case VK_PRIOR:
                keyCode = KeyCode.VK_PAGE_UP;
                break;
            case VK_NEXT:
                keyCode = KeyCode.VK_PAGE_DOWN;
                break;
            case VK_HOME:
                keyCode = KeyCode.VK_HOME;
                break;
            case VK_END:
                keyCode = KeyCode.VK_END;
                break;

            case VK_OEM_7:
                keyCode = KeyCode.VK_QUOTE;
                break;
            case VK_OEM_3:
                keyCode = KeyCode.VK_BACK_QUOTE;
                break;
            case VK_OEM_2:
                keyCode = KeyCode.VK_DEAD_ACUTE;
                break;
            case VK_KANA:
                keyCode = KeyCode.VK_KANA;
                break;
            case VK_KANJI:
                keyCode = KeyCode.VK_KANJI;
                break;
            case VK_DBE_CODEINPUT:
            case VK_DBE_NOCODEINPUT:
                keyCode = KeyCode.VK_CODE_INPUT;
                break;
            default:
                keyCode = KeyCode.VK_UNDEFINED;
                break;
        }
        return keyCode;
    }

    public static final KeyLocation getKeyLocation(final int rawCode) {
        switch (rawCode) {
            case VK_LSHIFT:
            case VK_LCONTROL:
            case VK_LMENU:
            case VK_LWIN:
                return KeyLocation.LEFT;

            case VK_RSHIFT:
            case VK_RCONTROL:
            case VK_RMENU:
            case VK_RWIN:
                return KeyLocation.RIGHT;

            case VK_NUMPAD0:
            case VK_NUMPAD1:
            case VK_NUMPAD2:
            case VK_NUMPAD3:
            case VK_NUMPAD4:
            case VK_NUMPAD5:
            case VK_NUMPAD6:
            case VK_NUMPAD7:
            case VK_NUMPAD8:
            case VK_NUMPAD9:
            case VK_MULTIPLY:
            case VK_ADD:
            case VK_SUBTRACT:
            case VK_DECIMAL:
            case VK_DIVIDE:
            case VK_NUMLOCK:
                return KeyLocation.NUMPAD;
            default:
                return KeyLocation.MAIN;
        }
    }

    public static final int getEventMask(final int mask) {
        int evtMask = 0;

        if (((mask & MediaCodeSupport.MOD_LSHIFT) == MediaCodeSupport.MOD_LSHIFT)
                || ((mask & MediaCodeSupport.MOD_RSHIFT) == MediaCodeSupport.MOD_RSHIFT)) {
            evtMask |= InputEvent.MASK_SHIFT;
        }

        if (((mask & MediaCodeSupport.MOD_LCONTROL) == MediaCodeSupport.MOD_LCONTROL)
                || ((mask & MediaCodeSupport.MOD_RCONTROL) == MediaCodeSupport.MOD_RCONTROL)) {
            evtMask |= InputEvent.MASK_CTRL;
        }

        if (((mask & MediaCodeSupport.MOD_LWIN) == MediaCodeSupport.MOD_LWIN)
                || ((mask & MediaCodeSupport.MOD_RWIN) == MediaCodeSupport.MOD_RWIN)) {
            evtMask |= InputEvent.MASK_META;
        }

        if (((mask & MediaCodeSupport.MOD_LALT) == MediaCodeSupport.MOD_LALT)
                || ((mask & MediaCodeSupport.MOD_RALT) == MediaCodeSupport.MOD_RALT)) {
            evtMask |= InputEvent.MASK_ALT;
        }

        if ((mask & MediaCodeSupport.MOD_LBUTTON) == MediaCodeSupport.MOD_LBUTTON) {
            evtMask |= InputEvent.MASK_LBUTTON;
        }

        if ((mask & MediaCodeSupport.MOD_RBUTTON) == MediaCodeSupport.MOD_RBUTTON) {
            evtMask |= InputEvent.MASK_RBUTTON;
        }

        if ((mask & MediaCodeSupport.MOD_MBUTTON) == MediaCodeSupport.MOD_MBUTTON) {
            evtMask |= InputEvent.MASK_MBUTTON;
        }

        if ((mask & MediaCodeSupport.MOD_XBUTTON1) == MediaCodeSupport.MOD_XBUTTON1) {
            evtMask |= InputEvent.MASK_XBUTTON1;
        }

        if ((mask & MediaCodeSupport.MOD_XBUTTON2) == MediaCodeSupport.MOD_XBUTTON2) {
            evtMask |= InputEvent.MASK_XBUTTON2;
        }

        return evtMask;
    }
}
